package xcmg.device.web.materialsSchedule;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import xcmg.device.dao.entity.PriMaterialsDO;
import xcmg.device.dao.entity.materialsSchedule.MaterialsScheduleDO;
import xcmg.device.dao.entity.warehouse.WarehouseDO;
import xcmg.device.dao.mapper.CompanyInfoMapper;
import xcmg.device.infra.AuthCode;
import xcmg.device.infra.BasicController;
import xcmg.device.infra.ErrorCode;
import xcmg.device.infra.annotation.ExternalApiRequest;
import xcmg.device.infra.exception.CommonBusiExceptions;
import xcmg.device.service.ExternalParamCheckService;
import xcmg.device.service.audit.MaterialsScheduleAuditService;
import xcmg.device.service.crm.util.ActionResultUtil;
import xcmg.device.service.materialsSchedule.MaterialsScheduleService;
import xcmg.device.service.vo.FunctionResult;
import xcmg.device.service.vo.delivery.BusinessOrderAuditParamVO;
import xcmg.device.service.vo.delivery.ManualFinishVO;
import xcmg.device.service.vo.materialsSchedule.MaterialsScheduleAddVO;
import xcmg.device.service.vo.materialsSchedule.MaterialsScheduleDeliveryNoteDetailVO;
import xcmg.device.service.vo.materialsSchedule.MaterialsScheduleDetailVO;
import xcmg.device.service.vo.materialsSchedule.MaterialsScheduleVO;
import xcmg.device.service.vo.materialsSchedule.SelectDeliveryNoteVO;
import xcmg.device.service.warehouse.allot.RegionAllotService;
import yb.ecp.fast.infra.annotation.FastMappingInfo;
import yb.ecp.fast.infra.infra.ActionResult;
import yb.ecp.fast.infra.infra.PageCommonVO;
import yb.ecp.fast.infra.infra.SearchCommonVO;

import javax.servlet.http.HttpServletRequest;
import java.io.InputStream;
import java.util.Arrays;
import java.util.List;

@Api
@RestController
@RequestMapping("/materialsSchedule")
public class MaterialsScheduleController extends BasicController {
    @Autowired
    private MaterialsScheduleService materialsScheduleService;
    @Autowired
    private MaterialsScheduleAuditService materialsScheduleAuditService;

    @Autowired
    private ExternalParamCheckService externalParamCheckService;
    @Autowired
    private RegionAllotService regionAllotService;


    @RequestMapping(value = "/add",method = RequestMethod.POST)
    @ApiOperation(value = "增加领料单")
    @FastMappingInfo(needLogin = true)
    public ActionResult add (@RequestBody MaterialsScheduleAddVO materialsScheduleAddVO)throws Exception {
        if(materialsScheduleAddVO == null ){
            return actionResult(ErrorCode.IllegalArument);
        }
        materialsScheduleAddVO.getHeaderInfo().setCreateId(getUserId());
        materialsScheduleAddVO.getHeaderInfo().setCreateName(getUserName());
        materialsScheduleAddVO.getHeaderInfo().setCreatePartName(getDeptName());
        ErrorCode ret=ErrorCode.Success;
        if(!StringUtils.isEmpty(materialsScheduleAddVO.getHeaderInfo().getRequisitionNo())){
            ret=materialsScheduleService.update(materialsScheduleAddVO,getOrgId());
        }
        else {
            ret=materialsScheduleService.add(materialsScheduleAddVO,getOrgId());
        }
        return actionResult(ret);
    }

    @RequestMapping(value = "/remove",method = RequestMethod.POST)
    @ApiOperation(value = "删除领料单")
    @FastMappingInfo(needLogin = true,code = AuthCode.PickingBill.DEL)
    public ActionResult remove(@RequestBody String[] ids)throws Exception{
        if(ids==null||ids.length==0){
            return actionResult(ErrorCode.IllegalArument);
        }
        try {
            ErrorCode ret = materialsScheduleService.remove(Arrays.asList(ids));
            return actionResult(ret);
        }catch (Exception e){
             ActionResult actionResult=new ActionResult();
             actionResult.setCode(1);
             actionResult.setMessage(e.getMessage());
             return actionResult;
        }
    }

    @RequestMapping(value = "/update",method = RequestMethod.POST)
    @ApiOperation(value = "更新领料单")
    @FastMappingInfo(needLogin = true,code = AuthCode.PickingBill.EDIT)
    public ActionResult update(@RequestBody MaterialsScheduleAddVO materialsScheduleAddVO) throws Exception{
        if(materialsScheduleAddVO.getHeaderInfo().getId() == null){
            return actionResult(ErrorCode.MaterialsSchedule);
        }
        return actionResult(materialsScheduleService.update(materialsScheduleAddVO,getOrgId()));
    }

    @RequestMapping(value = "/list",method = RequestMethod.POST)
    @ApiOperation(value = "领料单列表")
    @FastMappingInfo(needLogin = true)
    public ActionResult list(@RequestBody SearchCommonVO<MaterialsScheduleVO> condition) throws Exception {
        MaterialsScheduleVO materialsScheduleVO=condition.getFilters();
        if(materialsScheduleVO==null){
            materialsScheduleVO=new MaterialsScheduleVO();
        }
        materialsScheduleVO.setOrgId(getOrgId());
        condition.setFilters(materialsScheduleVO);
        PageCommonVO pageCommonVO=materialsScheduleService.list(condition);
        return actionValueResult(pageCommonVO.getPageInfo());
    }

    @RequestMapping(value = "/item",method = RequestMethod.GET)
    @FastMappingInfo(needLogin = true)
    public ActionResult item(String id){
        if(StringUtils.isEmpty(id)){
            return actionResult(ErrorCode.IllegalArument);
        }
        return actionResult(ErrorCode.Success,materialsScheduleService.item(id));
    }

    @RequestMapping(value = "/itemGroupByOutLocation",method = RequestMethod.GET)
    @FastMappingInfo(needLogin = true)
    public ActionResult<List<MaterialsScheduleAddVO>> itemGroupByOutLocation(String id){
        if(StringUtils.isEmpty(id)){
            throw new CommonBusiExceptions(ErrorCode.IllegalArument.getDesc());
        }
        return actionResult(ErrorCode.Success,materialsScheduleService.itemGroupByArea(id));
    }

    //导出
    @RequestMapping(value = "/export",method = RequestMethod.POST)
    @FastMappingInfo(needLogin = true,code = AuthCode.PickingBill.EXPORT)
    public void export(String[] ids)throws Exception {
        materialsScheduleService.export(Arrays.asList(ids));
    }

    @RequestMapping(value = "/exportAll",method = RequestMethod.POST)
    @FastMappingInfo(needLogin = true,code = AuthCode.PickingBill.EXPORT)
    public void exportAll(MaterialsScheduleVO condition)throws Exception {
        condition.setOrgId(getOrgId());
        materialsScheduleService.exportAll(condition);
    }

    @ResponseBody
    @RequestMapping(value = "/importOut", method = RequestMethod.POST)
    @FastMappingInfo(needLogin = true)
    public ActionResult importOutExcel(HttpServletRequest request) throws Exception{
        MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
        MultipartFile file = multipartRequest.getFile( multipartRequest.getFileNames().next());
        String fileName = file.getOriginalFilename();
        FunctionResult<String> result=new FunctionResult<>();
        if (!fileName.trim().endsWith(".xls")) {
            result.setCode(ErrorCode.ImportExcelEndWithXLS);
        } else {
            InputStream in = file.getInputStream();
            result= materialsScheduleService.importExcel(in,  getOrgId(),1);
        }
        return actionResult(result.getCode(), result.getValue());
    }

    @ResponseBody
    @RequestMapping(value = "/importIn", method = RequestMethod.POST)
    @FastMappingInfo(needLogin = true)
    public ActionResult importInExcel(HttpServletRequest request) throws Exception{
        MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
        MultipartFile file = multipartRequest.getFile( multipartRequest.getFileNames().next());
        String fileName = file.getOriginalFilename();
        FunctionResult<String> result=new FunctionResult<>();
        if (!fileName.trim().endsWith(".xls")) {
            result.setCode(ErrorCode.ImportExcelEndWithXLS);
        } else {
            InputStream in = file.getInputStream();
            result= materialsScheduleService.importExcel(in,  getOrgId(),0);
        }
        return actionResult(result.getCode(), result.getValue());
    }

    @RequestMapping(value = "/downloadOut",method = RequestMethod.POST)
    @FastMappingInfo(needLogin = true)
    public void downloadOut() throws Exception {
        materialsScheduleService.download(1);
    }
    @RequestMapping(value = "/downloadIn",method = RequestMethod.POST)
    @FastMappingInfo(needLogin = true)
    public void downloadIn() throws Exception {
        materialsScheduleService.download(0);
    }

    @RequestMapping(value = "/manualFinishIn", method = RequestMethod.POST)
    @ApiOperation("强制完成单据")
    public ActionResult manualFinishIn(@RequestBody ManualFinishVO manualFinishVO) throws Exception
    {
        return actionResult(materialsScheduleService.manualFinish(manualFinishVO.getBillNo(), manualFinishVO.getMaterialsNo(), getOrgId(),0));
    }


    @RequestMapping(value = "/manualFinishOut", method = RequestMethod.POST)
    @ApiOperation("强制完成单据")
    public ActionResult manualFinishOut(@RequestBody ManualFinishVO manualFinishVO) throws Exception
    {
        return actionResult(materialsScheduleService.manualFinish(manualFinishVO.getBillNo(), manualFinishVO.getMaterialsNo(), getOrgId(),1));
    }

    @RequestMapping(value = "/receiptConfirm", method = RequestMethod.POST)
    @FastMappingInfo(needLogin = true)
    public ActionResult receiptConfirm(@RequestBody MaterialsScheduleVO condition) {
        return actionResult(materialsScheduleService.receiptConfirm(condition.getId(), getUserName()));
    }

//    /**
//     * 大厂库存查询接口
//     *
//     * 320962182781075456
//     * 803081451,803081452
//     * @param materialsNo
//     * @return
//     */
//    @RequestMapping(value = "/sapStock", method = RequestMethod.GET)
//    @FastMappingInfo(needLogin = true)
//    public ActionResult sapStock(String materialsNo) {
//      try {
//        return actionResult(materialsScheduleService.sapStock(materialsNo, getOrgId()));
//      } catch (Exception e) {
//        return new ActionResult(ErrorCode.Failure.getCode(), e.getMessage());
//      }
//    }

    @RequestMapping(value = "/adjust", method = RequestMethod.POST)
    @ApiOperation(value = "领料单调整")
    @FastMappingInfo(needLogin = true)
    public ActionResult adjust(@RequestBody MaterialsScheduleAddVO materialsScheduleAddVO) {
        try {
            if (null == materialsScheduleAddVO.getHeaderInfo().getId() || CollectionUtils
                .isEmpty(materialsScheduleAddVO.getDetailList())) {
                return actionResult(ErrorCode.MaterialsSchedule);
            }
            materialsScheduleService.adjust(materialsScheduleAddVO, getOrgId());
        } catch (Exception e) {
            return new ActionResult(ErrorCode.Failure.getCode(), e.getMessage());
        }
        return actionResult(ErrorCode.Success);
    }

    @Autowired
    private CompanyInfoMapper companyInfoMapper;


    @RequestMapping(value = "/add4External",method = RequestMethod.POST)
    @ApiOperation(value = "外部接口-塔机增加领料单")
    @ExternalApiRequest
    public ActionResult add4External (@RequestBody MaterialsScheduleAddVO materialsScheduleAddVO)throws Exception {
        if(materialsScheduleAddVO == null ){
            return actionResult(ErrorCode.IllegalArument);
        }
        materialsScheduleAddVO.getHeaderInfo().setCreateId("tj-user");
        materialsScheduleAddVO.getHeaderInfo().setCreateName("tj-user");

        String orgId = companyInfoMapper.getOrgIdBySapCode(materialsScheduleAddVO.getSapCode());
        if (StringUtils.isBlank(orgId)) {
            return actionResult(ErrorCode.Failure,"sapCode错误");
        }
        //crmOrder重复单号校验
        ActionResult crmOrderDulpCheck = crmOrderDulpCheck(materialsScheduleAddVO);
        if(crmOrderDulpCheck != null && successActionResult(crmOrderDulpCheck)){
            return crmOrderDulpCheck;
        }
        //参数预处理，包括默认参数赋值或者缺失参数填充
        ActionResult actionResult = addExternalParamPreHandle(materialsScheduleAddVO, orgId);
        if(!successActionResult(actionResult)){
            return actionResult;
        }
        return actionValueResult(materialsScheduleService.add4External(materialsScheduleAddVO,orgId));
    }

    /**判断crmOrder是否已经存在记录，如果存在则返回操作成功，同时返回存在的PMS编号--
     这么返回的原因crm调接口大多加在签核流程里面，多次点击触发接口，返回已存在，会影响签核的动作（具体可以问瑞泰-黄远辉）
    返回null代表流程可以继续往下走，返回code=0表示已经存在数据，直接返回已存在的数据*/
    private ActionResult crmOrderDulpCheck(MaterialsScheduleAddVO materialsScheduleAddVO) {
        String crmOrder = materialsScheduleAddVO.getHeaderInfo().getCrmOrder();
        if(StringUtils.isEmpty(crmOrder)){
            return actionResult(ErrorCode.Failure,"crm订单号不能为空","crm订单号不能为空");
        }
        List<MaterialsScheduleDO> schedules = materialsScheduleService.getMaterialsScheduleByCrmOrder(crmOrder);
        if(!CollectionUtils.isEmpty(schedules)){
            return actionResult(ErrorCode.Success,"CRM单号已存在",schedules.get(0).getRequisitionNo());
        }
        return null;
    }
    /**
     * 塔机增加领料单参数初始化处理*/
    private ActionResult addExternalParamPreHandle(MaterialsScheduleAddVO materialsScheduleAddVO,String orgId){

        MaterialsScheduleVO headerInfo = materialsScheduleAddVO.getHeaderInfo();
        //默认参数赋值
        headerInfo.setCreateId("477477706045325312");
        headerInfo.setCreateName("接口用户");
        headerInfo.setCreatePartName("服务部");
        headerInfo.setCreatePartId("455404133906644992");

        //1、类型：0从成产领料 主表in_location:调入仓库，in_area:调入库区，sap_in_area=in_area，out_location:调出仓库​
        //2、类型：1从备件领料，主表：in_location:调入仓库，​out_location:调出仓库，out_area:调出库区，sap_out_area=out_are
        Integer type = headerInfo.getType();
        if(type != null && type.compareTo(1) == 0){
            //如果类型时1的话，根据outWareHouse匹配仓库编码，然后将编码赋值给outLocation,outArea,sapOutArea
            String outWarehouse = headerInfo.getOutWarehouse();
            if(StringUtils.isEmpty(outWarehouse)){
                actionResult(ErrorCode.Failure,"调出仓库名称不能为空","调出仓库名称不能为空");
            }
            List<WarehouseDO> outwarehouse = regionAllotService.getWareHousesByOrgAndDescription(orgId, outWarehouse);
            if(outwarehouse.size() < 1){
                return actionResult(ErrorCode.Failure,"调出仓库名称:"+outWarehouse+"无法匹配仓库","调出仓库名称:"+outWarehouse+"无法匹配仓库");
            }
            String outArea =outwarehouse.get(0).getWarehouseCode();
            headerInfo.setOutLocation(outArea);
            headerInfo.setSapOutArea(outArea);
            headerInfo.setOutArea(outArea);
        }else{
            String inArea = headerInfo.getInArea();
            headerInfo.setSapInArea(inArea);
        }
        List<MaterialsScheduleDetailVO> detailList = materialsScheduleAddVO.getDetailList();
        String inLocation = headerInfo.getInLocation();
        String outLocation = headerInfo.getOutLocation();
        for(MaterialsScheduleDetailVO detailVO : detailList){
            //所有的子表中的inLocal和outLocal从主表中获取
            if(!StringUtils.isEmpty(inLocation)){
                detailVO.setInLocation(inLocation);
            }
            if(!StringUtils.isEmpty(outLocation)){
                detailVO.setOutLocation(outLocation);
            }
            //拼接零件的单位信息unit
            String materialNo = detailVO.getMaterialsNo();
            PriMaterialsDO materialsInfo = externalParamCheckService.getMaterialsInfo(materialNo);
            if(materialsInfo != null){
                String unit = materialsInfo.getUnit();
                detailVO.setUnit(unit);
                String materialsDes = materialsInfo.getMaterialsDes();
                if(!StringUtils.isEmpty(materialsDes)){
                    detailVO.setMaterialsDes(materialsDes);
                }
            }
        }
        return new ActionResult(ErrorCode.Success);
    }

    @FastMappingInfo(needLogin = true)
    @ApiOperation("领料单审核通过-给塔机用的")
    @RequestMapping(value = "/auditPass",method = RequestMethod.POST)
    public ActionResult auditPass(@RequestBody MaterialsScheduleAddVO materialsScheduleAddVO) throws Exception {
        return actionResult(materialsScheduleService.auditPass(materialsScheduleAddVO,getOrgId()));
    }

    @RequestMapping(value = "/auditRefuse",method = RequestMethod.POST)
    @FastMappingInfo(needLogin = true)
    @ApiOperation("领料单审核拒绝-给塔机用的")
    public ActionResult auditRefuse(@RequestBody MaterialsScheduleAddVO materialsScheduleAddVO){
        return actionResult(materialsScheduleService.auditRefuse(materialsScheduleAddVO));
    }

//    @PostMapping("/syncCrm")
//    public ActionResult syncCrm(@RequestBody String[] ids) {
//        for (String id : ids) {
//            materialsScheduleService.syncCrm(id);
//        }
//        return actionResult(ErrorCode.Success);
//    }

    /**
     * @Des 领料单审核通过
     * @Date 2021/4/14 10:27
     * @Author wangzhaoyu
     * @Param [param]
     * @Return yb.ecp.fast.infra.infra.ActionResult
     */
    @RequestMapping(value = "/commonAuditPass" , method = RequestMethod.POST)
    @FastMappingInfo(needLogin = true)
    public ActionResult commonAuditPass(@RequestBody BusinessOrderAuditParamVO param){
        String userId = getUserId();
        String userName = getUserName();
        try{
            ActionResult auditResult = materialsScheduleAuditService.audit(param, userId, userName, true);
            return auditResult;
        }catch (Exception e){
            return ActionResultUtil.errorActionResult(ErrorCode.Failure.getCode(),e.getMessage());
        }
    }

    /**
     * @Des 领料单审核拒绝
     * @Date 2021/4/14 10:52
     * @Author wangzhaoyu
     * @Param [param]
     * @Return yb.ecp.fast.infra.infra.ActionResult
     */
    @FastMappingInfo(needLogin = true)
    @RequestMapping(value = "/commonAuditReject" , method = RequestMethod.POST)
    public ActionResult commonAuditReject(@RequestBody BusinessOrderAuditParamVO param){
        String userId = getUserId();
        String userName = getUserName();
        try{
            ActionResult auditResult = materialsScheduleAuditService.audit(param, userId, userName, false);
            return auditResult;
        }catch (Exception e){
            return ActionResultUtil.errorActionResult(ErrorCode.Failure.getCode(),e.getMessage());
        }
    }
    /**
     * @Des 页面看板，领料单待审核数据
     * @Date 2021/4/14 11:45
     * @Author wangzhaoyu
     * @Param []
     * @Return yb.ecp.fast.infra.infra.ActionResult
     */
    @RequestMapping(value = "/mainBoardWaitAudit" , method = RequestMethod.GET)
    @FastMappingInfo(needLogin = true)
    public ActionResult mainBoardWaitAudit() throws Exception {

        String orgId = getOrgId();
        //查询当前机构未删除，已提交的待审核数据
        Integer waitDataCount = materialsScheduleService.countAuditData(orgId);
        return ActionResultUtil.successActionResult(waitDataCount);
    }

    /**
     * @Des 备件从生产领料时选择发货通知单接口
     * @Date 2021/6/1 16:54
     * @Author wangzhaoyu
     * @Param [deliveryNoteNo, pageSize, pageNum]
     * @Return yb.ecp.fast.infra.infra.ActionResult
     */
    @GetMapping("/selectDeliveryNotes")
    @FastMappingInfo(needLogin = true)
    public ActionResult selectDeliveryNotes(String deliveryNoteNo,Integer pageNum,Integer pageSize) throws Exception {
        //
        pageNum = pageNum == null ? 1 : pageNum;
        pageSize = pageSize == null ? 10 : pageSize;
        String orgId = getOrgId();
        PageCommonVO<SelectDeliveryNoteVO> result = materialsScheduleService.selectDeliveryNotes(orgId,deliveryNoteNo,pageNum,pageSize);
        return ActionResultUtil.successActionResult(result.getPageInfo());
    }

    /**
     * @Des 领料单选择发货通知单时展示零件信息
     * @Date 2021/6/1 17:56
     * @Author wangzhaoyu
     * @Param [id]
     * @Return yb.ecp.fast.infra.infra.ActionResult
     */
    @GetMapping("/deliveryNoteDetails")
    @FastMappingInfo(needLogin = true)
    public ActionResult deliveryNoteDetails(String deliveryNoteId) {
        List<MaterialsScheduleDeliveryNoteDetailVO> resultData = materialsScheduleService.deliveryNoteDetails(deliveryNoteId);
        return ActionResultUtil.successActionResult(resultData);
    }

//    @GetMapping("/pullMaterialTaskInfo")
//    public ActionResult pullMaterialTaskInfo() throws Exception {
//    	materialsTask.pullMaterialsAndMarket();
//    	return actionResult(ErrorCode.Success);
//    }
}
